package com.func.domain.activity.service.partake;

import com.func.domain.activity.model.aggregate.CreatePartakeOrderAggregate;
import com.func.domain.activity.model.entity.ActivityEntity;
import com.func.domain.activity.model.entity.PartakeRaffleActivityEntity;
import com.func.domain.activity.model.entity.UserRaffleOrderEntity;
import com.func.domain.activity.model.valobj.ActivityStateVO;
import com.func.domain.activity.repository.IActivityRepository;
import com.func.domain.activity.service.IRaffleActivityPartakeService;
import com.func.types.enums.ResponseCode;
import com.func.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.Date;

/**
 * <p>
 * AbstractRaffleActivityPartake
 * </p>
 *
 * @author Simon
 * @version 2025.03.14.1.0.0
 * @description
 * @since 2025-03-14
 */

@Slf4j
public abstract class AbstractRaffleActivityPartake implements IRaffleActivityPartakeService {
    @Resource
    private IActivityRepository activityRepository;

    @Override
    public UserRaffleOrderEntity createOrder(PartakeRaffleActivityEntity partakeRaffleActivityEntity) {

        // 0. 基信信息
        String userId = partakeRaffleActivityEntity.getUserId();
        Long activityId = partakeRaffleActivityEntity.getActivityId();

        log.info("创建活动抽奖单开始 userId: {} activityId: {}", userId, activityId);
        // 1.  活动查询
        ActivityEntity activityEntity = activityRepository.queryRaffleActivityByActivityId(activityId);

        // 1.1 校验 : 活动状态
        if (!ActivityStateVO.open.getCode().equals(activityEntity.getState())) {
            throw new AppException(ResponseCode.ACTIVITY_STATE_ERROR.getCode(), ResponseCode.ACTIVITY_STATE_ERROR.getInfo());
        }

        // 1.2 校验 : 活动日期
        Date current = new Date();
        if (activityEntity.getBeginDateTime().after(current) || activityEntity.getEndDateTime().before(current)){
            log.error("创建活动抽奖单失败, 活动状态未开启 activityId: {} state: {}", activityId, activityEntity.getState());
            throw new AppException(ResponseCode.ACTIVITY_DATE_ERROR.getCode(), ResponseCode.ACTIVITY_DATE_ERROR.getInfo());
        }

        // 2. 查询未被使用的互动参与订单
        UserRaffleOrderEntity userRaffleOrderEntity = activityRepository.queryNoUsedRaffleOrder(partakeRaffleActivityEntity);
        if (null != userRaffleOrderEntity) {
            log.info("创建参与活动订单 userId: {} activityId: {} userRaffleOrderEntity: {}", userId, activityId, userRaffleOrderEntity);
            return userRaffleOrderEntity;
        }

        // 3. 额度账户过滤&返回账户构建对象
        CreatePartakeOrderAggregate createPartakeOrderAggregate = this.doFilterAccount(userId, activityId, new Date());

        // 4. 构建订单
        UserRaffleOrderEntity userRaffleOrder = this.buildUsrRaffleOrder(userId, activityId, new Date());

        // 5. 填充抽奖单实体对象
        createPartakeOrderAggregate.setUserRaffleOrderEntity(userRaffleOrder);

        // 6. 保存聚合对象, 一个领域内的一个聚合是一个事务操作
        activityRepository.saveCreatePartakeOrderAggregate(createPartakeOrderAggregate);

        log.info("创建活动抽奖单结束 userId: {} activityId: {} orderId: {}", userId, activityId, userRaffleOrder.getOrderId());
        // 7. 返回订单信息
        return userRaffleOrder;
    }

    @Override
    public UserRaffleOrderEntity createOrder(String userId, Long activityId) {
        return createOrder(PartakeRaffleActivityEntity.builder()
                .userId(userId)
                .activityId(activityId)
                .build());
    }

    /**
     * 过滤账户, 保证用户有足够的额度参与活动
     * @param userId 用户Id
     * @param activityId 活动Id
     * @param currentDate 日期
     * @return 用户参与抽奖订单聚合对象
     */
    protected abstract CreatePartakeOrderAggregate doFilterAccount(String userId, Long activityId, Date currentDate);

    /**
     * 构建用户抽奖订单实体
     * @param userId 用户Id
     * @param activityId 活动Id
     * @param currentDate 日期
     * @return 用户活动抽奖订单实体
     */
    protected abstract UserRaffleOrderEntity buildUsrRaffleOrder(String userId, Long activityId, Date currentDate);
}